package team.pwy.testUtil;

import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import redis.clients.jedis.Jedis;
import team.pwy.GameLeaderboard;
import team.pwy.consts.RbmConsts;
import team.pwy.mapper.*;
import team.pwy.pojo.entity.*;
import team.pwy.service.*;
import team.pwy.util.CreatJedis;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @title: AutoStart
 * @author: DaiLing
 * @description: 项目启动运行此类更新数据
 * @date: 2024/1/24 10:50
 */
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class AutoStart {

    @Resource
    private SeatService seatService;

    @Resource
    private PhoneService phoneService;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private SeckillMapper seckillMapper;

    @Resource
    private MovieMapper movieMapper;

    @Resource
    private SeckillService seckillService;

    @Resource
    private MovieIndexRepository movieIndexRepository;

    @Resource
    private TypeIndexRepository typeIndexRepository;

    @Resource
    private TypeMapper typeMapper;

    @Resource
    private CouponMapper couponMapper;

    @Resource
    private MovieIndexService movieIndexService;

    @Resource
    private SessionMapper sessionMapper;

    private Jedis jedis;

    Set<Long> timeSet = new HashSet<>();

    @Test
    public void start() {

        // 加载商品到redis
        loadingSeckill();

        // 加载电话号码到redis
        loadingPhone();

        // 加载座位到redis
        loadingSeat();

        // 加载电影到redis
        loadingMovie();

        // 加载电影到ES
        loadingMovieToES();

        // 加载电影类型到ES
        loadingTypeToES();

        // 加载优惠卷过期提醒队列redis过期key
        loadingCoupon();

        // 加载电影场次开场队列redis过期key
        loadingSession();

        // 加载观影记录队列redis过期key
        loadingLookOld();
    }

    public AutoStart() {
        jedis = CreatJedis.getJedis();
        jedis.flushDB();
    }

    /**
     * @author DaiLing
     * @description 加载观影记录redis过期key
     * @date 2024/2/4 17:09
     */
    private void loadingLookOld() {
        List<Session> sessionList = sessionMapper.findStartSessionEnd();

        for (Session session : sessionList) {
            long time = session.getEndTime().getTime() - new Date().getTime();
            while (timeSet.contains(time)) {
                time += 300;
            }
            timeSet.add(time);
            redisTemplate.opsForValue().set("lookOld:" + session.getId(), session.getId(), time, TimeUnit.MILLISECONDS);
        }
    }

    /**
     * @author DaiLing
     * @description 加载电影场次开场redis过期key
     * @date 2024/2/4 17:10
     */
    private void loadingSession() {
        List<Session> sessionList = sessionMapper.findStartSessionBefor();
        for (Session session : sessionList) {

            long time = session.getStarTime().getTime() - new Date().getTime() - 2 * 60 * 60 * 1000;
            while (timeSet.contains(time)) {
                time += 300;
            }
            timeSet.add(time);
            redisTemplate.opsForValue().set("sessionTip:" + session.getId(), session.getId(), time, TimeUnit.MILLISECONDS);
        }
    }

    /**
     * @author DaiLing
     * @description 加载优惠卷redis过期key
     * @date 2024/2/5 17:23
     */
    public void loadingCoupon() {
        List<Coupon> couponList = couponMapper.findByTimeBefore();
        for (Coupon coupon : couponList) {
            // 遍历用户的优惠券是否过期
            long time = coupon.getUpdatedBy().getTime() - new Date().getTime() - 2 * 60 * 60 * 1000;
            while (timeSet.contains(time)) {
                time += 300;
            }
            timeSet.add(time);
            redisTemplate.opsForValue().set("couponNext:" + coupon.getId(), coupon.getUserId(), time, TimeUnit.MILLISECONDS);

            time = coupon.getUpdatedBy().getTime() - new Date().getTime();
            while (timeSet.contains(time)) {
                time += 300;
            }
            redisTemplate.opsForValue().set("couponEnd:" + coupon.getId(), coupon.getUserId(), time, TimeUnit.MILLISECONDS);
        }

        List<Coupon> couponLists = couponMapper.findByTimeAfter();

        for (Coupon coupon : couponLists) {
            // 两小时之类
            long time = coupon.getUpdatedBy().getTime() - new Date().getTime();
            while (timeSet.contains(time)) {
                time += 300;
            }
            timeSet.add(time);
            redisTemplate.opsForValue().set("couponEnd:" + coupon.getId(), coupon.getUserId(), time, TimeUnit.MILLISECONDS);
        }
    }

    // 加载商品到redis
    public void loadingSeckill() {

        // 加载秒杀商品
        seckillService.findSeckillActive();

        List<Seckill> beforeActive = seckillMapper.findBeforeActiveIds();
        // 发送活动开始前队列
        for (Seckill seckill : beforeActive) {
            Map<String, Integer> map = new HashMap<>();
            map.put("seckillId", seckill.getId());
            map.put("status", 0);
            // 发送活动开始前队列
            rabbitTemplate.convertAndSend(RbmConsts.SECKILL_EX, RbmConsts.SECKILL_EC_QUEUE_RK, map, msg -> {
                msg.getMessageProperties().setHeader("x-delay", seckill.getStarTime().getTime() - new Date().getTime() - 1000);
                return msg;
            });
            map.put("status", 1);
            // 发送活动结束队列
            rabbitTemplate.convertAndSend(RbmConsts.SECKILL_EX, RbmConsts.SECKILL_EC_QUEUE_RK, map, msg -> {
                msg.getMessageProperties().setHeader("x-delay", seckill.getEndTime().getTime() - new Date().getTime() - 1000);
                return msg;
            });
        }
    }

    // 加载手机号到redis
    public void loadingPhone() {
        List<Phone> phone = phoneService.findAllPhone();
        ListOperations phoneLop = redisTemplate.opsForList();
        phoneLop.leftPush("phone", phone);
    }

    // 加载座位到redis
    public void loadingSeat() {
        // 加载座位
        List<Seat> seatList = seatService.findByStatus(1);
        for (Seat seat : seatList) {
            jedis.sadd("seat", String.valueOf(seat.getId()));
        }
    }

    // 加载电影排行
    public void loadingMovie() {
        // 加载所有电影
        GameLeaderboard leaderboard = new GameLeaderboard();

        // 更新得分
        List<Movie> allMovie = movieMapper.findAll();
        for (Movie movie : allMovie) {
            leaderboard.updateScore(movie.getId() + "&" + movie.getTitle() + "&" + movie.getPosterImg(), movie.getGrossed());
        }
    }

    // 加载电影到ES
    public void loadingMovieToES() {

        movieIndexService.initIndex();

        List<Movie> movieLis = movieMapper.findAll();
        List<MovieIndex> movieIndexList = new ArrayList<>();
        for (Movie movie : movieLis) {
            MovieIndex movieIndex = new MovieIndex();
            movieIndex.setId(movie.getId());
            movieIndex.setTitle(movie.getTitle());
            movieIndex.setPosterImg(movie.getPosterImg());
            movieIndex.setLanguage(movie.getLanguage());
            movieIndex.setDirector(movie.getDirector());
            movieIndex.setCountry(movie.getCountry());
            movieIndex.setDuration(Float.valueOf(movie.getDuration()));
            movieIndex.setFirstDate(movie.getFirstDate());
            movieIndex.setContent(movie.getContent());
            movieIndex.setNumbers(movie.getNumbers());
            movieIndex.setScore(movie.getScore());
            movieIndex.setGrossed(movie.getGrossed());
            movieIndex.setStatus(String.valueOf(movie.getStatus()));
            movieIndex.setSwiper(movie.getSwiper());
            movieIndex.setPrice(movie.getPrice());
            movieIndex.setRecommend(movie.getRecommend());
            movieIndex.setDesire(movie.getDesire());
            movieIndex.setCreateTime(movie.getCreateTime());
            movieIndexList.add(movieIndex);
        }
        movieIndexRepository.saveAll(movieIndexList);
    }

    // 加载电影类型到ES
    public void loadingTypeToES() {

        List<Type> typeList = typeMapper.findAll();
        List<TypeIndex> typeIndexList = new ArrayList<>();
        for (Type type : typeList) {
            TypeIndex typeIndex = new TypeIndex();
            typeIndex.setId(type.getId());
            typeIndex.setMoveId(type.getMoveId());
            typeIndex.setLove(type.getLove());
            typeIndex.setComedy(type.getComedy());
            typeIndex.setAnimation(type.getAnimation());
            typeIndex.setStory(type.getStory());
            typeIndex.setHorror(type.getHorror());
            typeIndex.setFrightened(type.getFrightened());
            typeIndex.setScienceFiction(type.getScienceFiction());
            typeIndex.setAction(type.getAction());
            typeIndex.setSuspense(type.getSuspense());
            typeIndex.setCrime(type.getCrime());
            typeIndex.setAdventure(type.getAdventure());
            typeIndex.setWarfare(type.getWarfare());
            typeIndex.setStrange(type.getStrange());
            typeIndex.setMovement(type.getMovement());
            typeIndex.setFamily(type.getFamily());
            typeIndex.setAncientCostume(type.getAncientCostume());
            typeIndex.setSwordsman(type.getSwordsman());
            typeIndex.setWest(type.getWest());
            typeIndex.setHistory(type.getHistory());
            typeIndex.setSpecialNote(type.getSpecialNote());
            typeIndex.setSongDance(type.getSongDance());
            typeIndex.setFilmNoir(type.getFilmNoir());
            typeIndex.setShorts(type.getShorts());
            typeIndex.setDocumentary(type.getDocumentary());
            typeIndex.setTraditional(type.getTraditional());
            typeIndex.setMusic(type.getMusic());
            typeIndex.setCalamity(type.getCalamity());
            typeIndex.setYouth(type.getYouth());
            typeIndex.setChildren(type.getChildren());
            typeIndex.setAnime(type.getAnime());
            typeIndex.setOther(type.getOther());
            typeIndex.setCreateTime(type.getCreateTime());
            typeIndexList.add(typeIndex);
        }
        typeIndexRepository.saveAll(typeIndexList);
    }
}
